package com.smartcommunity.service.dataImport;

import cn.hutool.core.util.StrUtil;
import com.smartcommunity.base.bean.ExceptionCode;
import com.smartcommunity.base.common.CacheMap;
import com.smartcommunity.base.common.DataImport;
import com.smartcommunity.bean.constant.Constant;
import com.smartcommunity.bean.entity.ImportErrorMsg;
import com.smartcommunity.bean.entity.ImportField;
import com.smartcommunity.controller.DataImportBase;
import com.smartcommunity.dao.village.HouseDao;
import com.smartcommunity.elasticsearch.house.HouseEsApi;
import com.smartcommunity.entity.village.Building;
import com.smartcommunity.entity.village.House;
import com.smartcommunity.exception.BusinessException;
import com.smartcommunity.log.interceptor.Log;
import com.smartcommunity.service.dataImport.model.HouseExportModel;
import com.smartcommunity.service.village.VillageService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.apache.commons.lang3.StringUtils.length;

/**
 * @ClassName: HouseData
 * @Description: 实有房屋导入
 * @author: minsheng
 * @Date: 2019/1/8 16:35
 * @Company:
 * @version V1.5.0
 */
@Component("house")
@Slf4j
public class HouseData extends DataImportBase implements DataImport {

    @Autowired
    private HouseDao dao;
    @Autowired
    private HouseEsApi houseEsApi;

    @Autowired
    private VillageService villageService;
    /**
     * 模板类型
     */
    private String type = "房屋";

    /**
     * 内容标题
     */
    private  String[] headerTitle = new String[]{"楼栋编号","房间号","房屋类型"};

    /**
     * 错误信息
     */
    private  String[] headerErrorMsg = new String[]{"为空、或当前小区没有此编号、或长度超过64位",
                                                    "为空、或长度超过20位",""};

    /**
     * key taskId,value progress
     */
    final int cacheSize = 100000;
    Map<String, Integer> progressTag = new LinkedHashMap<String, Integer>((int) Math.ceil(cacheSize / 0.75f) + 1, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<String, Integer> eldest) {
            return size() > cacheSize;
        }
    };

    @Override
    @Transactional
    @Log(info = "房屋模板导入")
    public String importData(List list, String villageCode,String fileName, String taskId,HttpServletResponse response) {
        progressTag.put(taskId, 10);
        //根据小区编号获取所有的楼栋信息
        Map<String, Building> buildMap = villageService.getBuildMapByVillageCode(villageCode);

        //初始化导入模板信息
        ImportErrorMsg msg = getFiledInfo(type,headerTitle,headerErrorMsg);

        //字段校验信息
        List<ImportField> fieldList = msg.getFieldList();

        if (StringUtils.isBlank(villageCode)){
            throw new IllegalArgumentException("小区编号为空！");
        }
        List<House> data = new ArrayList();

        List<Object[]> objList = (List<Object[]>) list;
        //存储错误信息
        List<HouseExportModel> dataListCopy = new ArrayList<>();

        int errorCount = 0;
        int size = objList.size();
        for (int i = 0; i < size; i++) {
            boolean isError = false;

            int currentRow = Constant.START_ROW + i;
            Object[] objects = objList.get(i);

            // 列长度校验，防止导入文件的列被删除
            int fixColumnLen = 3;
            if(objects.length < fixColumnLen){
                throw new BusinessException("模板文件列数不对，请检查模板文件！");
            }

            // 空行校验，跳过空行
            List<String> oneLine = Arrays.stream(objects)
                    .map(o -> StrUtil.trim(Objects.toString(o, EMPTY)))
                    .collect(Collectors.toList());
            if(oneLine.stream().allMatch(StrUtil::isEmpty)){
                log.info("第{}行全为空，跳过该行",currentRow);
                continue;
            }

            House house = new House();
            // 小区编号(必填)
            house.setVillageCode(villageCode);

            StringBuffer errorMessages = new StringBuffer();
            // 楼栋编号(必填)
            String buildingNo = String.valueOf(objects[0]) == "null" ? "" : String.valueOf(objects[0]);
            if (StringUtils.isBlank(buildingNo)
                    || !buildMap.containsKey(buildingNo)
                    || length(buildingNo)>64){
                //添加错误的行数
//                SetErrorRow(headerTitle[0],currentRow,fieldList);
                String errorMsg = appendErrorMsg(fieldList.get(0).getTitle(), buildingNo, fieldList.get(0).getErrorMsg());
                errorMessages.append(errorMsg);
                isError = true;
            }else{
                house.setBuildingNo(buildingNo);
            }

            // 房间号(必填)
            String houseNo = String.valueOf(objects[1]) == "null" ? "" : String.valueOf(objects[1]);
            if (StringUtils.isBlank(houseNo)){
                //添加错误的行数
//                SetErrorRow(headerTitle[1],currentRow,fieldList);
                String errorMsg = appendErrorMsg(fieldList.get(1).getTitle(), buildingNo, fieldList.get(1).getErrorMsg());
                errorMessages.append(errorMsg);
                isError = true;
            }else{
                house.setHouseNo(houseNo);
            }

            // 房间类型
            String houseType = String.valueOf(objects[2]) == "null" ? "" : String.valueOf(objects[2]);
            if (StringUtils.isBlank(houseType)){
                house.setType(0);//默认其他
            }else{
                house.setType(CacheMap.HOUSE_NAME_MAP.get(houseType)==null? 0: CacheMap.HOUSE_NAME_MAP.get(houseType) );
            }

            if(isError){
                errorCount++;
                HouseExportModel exportModel = new HouseExportModel();
                exportModel.setBuildingNo(buildingNo);
                exportModel.setHouseNo(houseNo);
                exportModel.setHouseType(houseType);
                exportModel.setErrorMsg(errorMessages.toString());
                dataListCopy.add(exportModel);
            }else{
                data.add(house);
            }
        }

        try {
            progressTag.put(taskId,60);
            if(CollectionUtils.isNotEmpty(data)) {
                dao.insertHouse(data);
                houseEsApi.batchSaveOrUpdateHouse(data);
            }
            //正常的数据需要导入进去，错误的数据返回到Excel
            if (errorCount > 0) {
                String errorFileName = exportExcelToLocal(taskId,fileName,headerTitle,dataListCopy);
                progressTag.put(taskId,100);
                return errorFileName;
            }
        } catch (Exception e) {
            log.error("导入房屋信息失败，保存数据库异常！", e);
            throw new BusinessException(ExceptionCode.HOUSE_IMPORT_EXCEPTION_CODE,"导入房屋信息失败，保存数据库异常！");
        }
        log.info("房屋导入完成");
        progressTag.put(taskId,100);
        return "";
    }

    @Override
    public int getImportDataProgress(String taskId) {
        return progressTag.get(taskId) == null ? 0 : progressTag.get(taskId);
    }

}
